#include "chartutils.h"
#include "filepathmanager.h"
#include <algorithm>


QString ChartUtils::makeFilePath(const QDateTime &startTime, const QString &sampleName)
{
    QString date = startTime.date().toString("yyyy-MM-dd");
    QString time = startTime.time().toString("hh-mm-ss-zzz");
    QString dataDir = FilePathManager::instance()->chartDir();
    QString fileName = sampleName.trimmed().replace(QRegExp("[\\/:*?\"<>|]"), "_");
    return QString("%1/%2/{%3}-%4.txt").arg(dataDir).arg(date).arg(time).arg(fileName);
}

void ChartUtils::autosetAxiesRange(QValueAxis *pAxis, double maxValue, int baseScale, bool margin)
{
    Q_ASSERT(pAxis);
    baseScale = qMax(baseScale, 1);

    int divNums = 10; // 坐标轴刻度数
    int upper = qRound(maxValue); // 目标值
    int range = upper + (baseScale - upper % baseScale); // 最接近的量程
    while (margin && ((double)maxValue / range > 0.8))
    {// 目标值超过量程的80%，扩大量程
        range += baseScale;
    }

    pAxis->setRange(0, range);
    pAxis->setTickCount(divNums + 1);
}

bool ChartUtils::readChartData(const QString &path, QList<QPointF> &points)
{
    QFile file(path);
    if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        qDebug() << "warning: open file: " << path;
        return false;
    }

    QTextStream textStream(&file);
    QString data = textStream.readAll();
    file.close();

    QStringList dataList = data.split(",");
    if (dataList.length() < 1)
    {
        qDebug() << "warning: empty file: " << path;
        return false;
    }

    if (dataList[dataList.length() - 1].isEmpty())
    {
        dataList.removeLast();
    }

    int length = dataList.length();
    for (int i = 0; i < length; i++)
    {
        points.push_back(QPointF(i, dataList[i].toDouble()));
    }

    return true;
}


static bool max_y(const QPointF& a, const QPointF& b)
{
    return a.y() < b.y();
}

void ChartUtils::paintChart(const QString &path, QValueAxis *pAxisX, QValueAxis *pAxisY, QLineSeries *pLine, double xmax, double ymax, bool autosetAxiesRange)
{
    Q_ASSERT(pLine);
    Q_ASSERT(pAxisX);
    Q_ASSERT(pAxisY);

    QList<QPointF> points;
    ChartUtils::readChartData(path, points);

    xmax = (xmax > 0) ? xmax : (points.count() > 0) ? points.length() : 49;
    ymax = (ymax > 0) ? ymax : (points.count() > 0) ? std::max_element(points.begin(), points.end(), max_y)->y() : 100;

    if (autosetAxiesRange)
    {
        ChartUtils::autosetAxiesRange(pAxisX, xmax, 5, false);
        ChartUtils::autosetAxiesRange(pAxisY, ymax, 100, true);
    }
    else
    {
        pAxisX->setRange(0, xmax);
        pAxisY->setRange(0, ymax);
    }

    pLine->replace(points);
}
